package com.mu.controller;
 
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.mu.common.MsgType;
import com.mu.domain.ImageMessage;
import com.mu.domain.InputMessage;
import com.mu.domain.UserMessageRequest;
import com.mu.manger.MessageCallBack;
import com.mu.service.MessageService;
import com.mu.util.OutputMessage;
import com.mu.util.RemoteHttpUtils;
import com.mu.util.SHA1;
import com.mu.util.SerializeXmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import com.thoughtworks.xstream.XStream;
 
/**
 * @author shang
 */
@Slf4j
@Controller
@RequestMapping("/tencent")
public class TencentController {


    @Resource
    private RemoteHttpUtils remoteHttpUtils;
    @Resource
    private MessageService messageService;

    @Value("${xun.token}")
	private String token;


    @GetMapping("/getAccessToken/{appid}/{secret}")
    public void getAccessToken(@PathVariable("appid")String appid, @PathVariable("secret")String secret){
        Map<String, Object> requestMap = new HashMap<>(3);
        requestMap.put("grant_type", "client_credential");
        requestMap.put("appid", appid);
        requestMap.put("secret", secret);
        JSONObject asJsonObject = remoteHttpUtils.getAsJsonObject("https://api.weixin.qq.com/cgi-bin/token", requestMap);
        log.info("getAccessToken:{}", asJsonObject.toJSONString());
    }

    @RequestMapping(value = "/checkVerification", method = { RequestMethod.GET, RequestMethod.POST })
    @ResponseBody  
    public void checkVerification(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("进入chat");  
        boolean isGet = "get".equalsIgnoreCase(request.getMethod());
        if (isGet) {
            access(request, response);
        } else {  
            // 进入POST聊天处理  
            System.out.println("enter post");  
            try {  
                // 接收消息并返回消息  
                acceptMessage(request, response);  
            } catch (IOException e) {  
                log.error("接收消息失败", e);
            }  
        }  
    }  
  
    /**
     * 验证URL真实性
     *
     * @param request 入参
     * @param response 出参
     * @author shang
     */  
    private void access(HttpServletRequest request, HttpServletResponse response) {
        // 验证URL真实性
        System.out.println("进入验证access");
        // 微信加密签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echoStr = request.getParameter("echostr");
        List<String> params = new ArrayList<>();
        params.add(token);
        params.add(timestamp);
        params.add(nonce);
        // 1. 将token、timestamp、nonce三个参数进行字典序排序
        params.sort(String::compareTo);
        // 2. 将三个参数字符串拼接成一个字符串进行sha1加密
        String temp = SHA1.encode(params.get(0) + params.get(1) + params.get(2));
        if (temp.equals(signature)) {
            try {
                response.getWriter().write(echoStr);
                log.info("成功返回 echoStr：{}", echoStr);
            } catch (IOException e) {
                log.error("校验接口认证失败", e);
            }
        }
    }
  
    private void acceptMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {

        InputMessage inputMsg = messageHandler(request);
        // 取得消息类型  
        String msgType = inputMsg.getMsgType();  
        // 根据消息类型获取对应的消息内容  
        if (msgType.equals(MsgType.Text.toString())) {
            log.info("接收消息:{}", JSONObject.toJSONString(inputMsg));
            messageService.sendMessage(inputMsg, response);
        }  
        // 获取并返回多图片消息  
//        if (msgType.equals(MsgType.Image.toString())) {
//            System.out.println("获取多媒体信息");
//            System.out.println("多媒体文件id：" + inputMsg.getMediaId());
//            System.out.println("图片链接：" + inputMsg.getPicUrl());
//            System.out.println("消息id，64位整型：" + inputMsg.getMsgId());
//
//            OutputMessage outputMsg = new OutputMessage();
//            outputMsg.setFromUserName(inputMsg.getToUserName());
//            outputMsg.setToUserName(inputMsg.getFromUserName());
//            outputMsg.setCreateTime(returnTime);
//            outputMsg.setMsgType(msgType);
//            ImageMessage images = new ImageMessage();
//            images.setMediaId(inputMsg.getMediaId());
//            outputMsg.setImage(images);
//            System.out.println("xml转换：/n" + xs.toXML(outputMsg));
//            response.getWriter().write(xs.toXML(outputMsg));
//        }
    }

    private InputMessage messageHandler(HttpServletRequest request) throws IOException{
        // 处理接收消息
        ServletInputStream in = request.getInputStream();
        // 将POST流转换为XStream对象
        XStream xs = SerializeXmlUtil.createXstream();
        xs.processAnnotations(InputMessage.class);
        xs.processAnnotations(OutputMessage.class);
        // 将指定节点下的xml节点数据映射为对象
        xs.alias("xml", InputMessage.class);
        // 将流转换为字符串
        StringBuilder xmlMsg = new StringBuilder();
        byte[] b = new byte[4096];
        for (int n; (n = in.read(b)) != -1;) {
            xmlMsg.append(new String(b, 0, n, StandardCharsets.UTF_8));
        }
        // 将xml内容转换为InputMessage对象
        return  (InputMessage) xs.fromXML(xmlMsg.toString());
    }
}  
	